<template>
    <div class="excellent-custom">
        <div class="header">
            <div class="cell index">#</div>
            <div class="cell">宿舍号</div>
            <div class="cell">宿舍长</div>
            <div class="cell">专业</div>
        </div>
        <div class="rows-outer">
            <div
                class="rows-inner"
                :class="{ 'no-transition': noTransition }"
                :style="{ transform: `translateY(-${currentOffset}px)` }"
                ref="rowsInner"
            >
                <div
                    class="row"
                    v-for="(item, idx) in displayData"
                    :key="idx"
                    :class="{ even: idx % 2 === 1 }"
                >
                    <div class="cell index">{{ (idx % props.Data.length) + 1 }}</div>
                    <div class="cell">{{ item[0] }}</div>
                    <div class="cell">{{ item[1] }}</div>
                    <div class="cell">{{ item[2] }}</div>
                </div>
            </div>
        </div>
    </div>
</template>
<script setup>
import { computed, ref, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'
const props = defineProps({
    Data: {
        type: Array,
        default: () => []
    },
    rowNum: {
        type: Number,
        default: 3 // 一开始展示3行
    },
    scrollInterval: {
        type: Number,
        default: 2000 // 每2秒滚动一次
    }
})

// 填充空行让内容撑满，或为滚动准备双倍数据
const displayData = computed(() => {
    if (props.Data.length > props.rowNum) {
        // 数据多于可见行数时，复制一份数据用于无缝滚动
        return props.Data.concat(props.Data)
    }
    // 数据不足时，显示所有数据并补空行填满
    const arr = props.Data.slice(0, props.Data.length)
    while (arr.length < props.rowNum) {
        arr.push(['', '', ''])
    }
    return arr
})

const currentIndex = ref(0)
const rowHeight = ref(0)
const rowsInner = ref(null)
const noTransition = ref(false)
const currentOffset = computed(() => currentIndex.value * rowHeight.value)

let timer = null

const startScroll = () => {
    // 数据不足以滚动时，不开启定时器
    if (props.Data.length <= props.rowNum) return

    // 清除之前的定时器，防止重复启动
    stopScroll();

    timer = setInterval(() => {
        currentIndex.value++

        // 当currentIndex达到原始数据长度时，瞬间回到0实现无缝循环
        if (currentIndex.value >= props.Data.length) {
            noTransition.value = true // 临时关闭过渡
            currentIndex.value = 0
            // 强制浏览器重新计算样式，确保无transition生效
            void rowsInner.value.offsetWidth
            noTransition.value = false // 重新开启过渡
        }
    }, props.scrollInterval)
}

const stopScroll = () => {
    if (timer) clearInterval(timer)
}

onMounted(() => {
    // 在DOM更新后获取行高并启动滚动
    nextTick(() => {
        if (rowsInner.value) {
            const row = rowsInner.value.querySelector('.row')
            if (row) {
                 // 确保获取到正确的行高，包括border和margin
                const computedStyle = getComputedStyle(row);
                rowHeight.value = row.offsetHeight + parseInt(computedStyle.marginTop) + parseInt(computedStyle.marginBottom);
            } else if (props.Data.length > 0) {
                 // 如果没有数据行但有header，估算行高或等待数据
                 // 这里简单处理，如果后续有数据会watch触发startScroll
            }
             // 如果组件初始没有数据，等watch到数据变化时再启动滚动
            if (props.Data.length > props.rowNum) {
               startScroll();
            }
        }
    });
});

onBeforeUnmount(() => {
    stopScroll()
})

// 监听Data变化，重置滚动
watch(() => props.Data, (newData, oldData) => {
     // 只有当新数据有内容且比旧数据多时才重置并滚动，避免空数据时报错或不必要的重置
     if (newData && newData.length > props.rowNum && (!oldData || oldData.length <= props.rowNum)){
         currentIndex.value = 0;
         // 确保获取到行高再启动滚动
         nextTick(() => {
              if (rowsInner.value) {
                const row = rowsInner.value.querySelector('.row');
                if (row) {
                    const computedStyle = getComputedStyle(row);
                    rowHeight.value = row.offsetHeight + parseInt(computedStyle.marginTop) + parseInt(computedStyle.marginBottom);
                    startScroll();
                }
              }
         });
     } else if (newData && newData.length <= props.rowNum) {
         // 数据不足以滚动，停止动画并重置索引
         stopScroll();
         currentIndex.value = 0;
     } else if (!newData || newData.length === 0) {
         // 数据为空，停止动画并清空索引
         stopScroll();
         currentIndex.value = 0;
     }
}, { deep: true, immediate: true })
</script>

<style lang="scss">
.excellent-custom {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    font-size: 1.2vw;
    color: #fff;
    padding-top: 2.8vw;
    box-sizing: border-box;
}
.header {
    display: flex;
    background: rgba(0,255,255,0.08);
    font-weight: bold;
    color: #00ffea;
    font-size: 0.8vw;
    flex-shrink: 0;
    border-bottom: 1px solid #00ffea;
}
.cell {
    flex: 1;
    text-align: center;
    padding: 0.8vw 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.index {
    flex: 0.7;
}
.rows-outer {
    flex: 1;
    overflow: hidden;
    position: relative;
}
.rows-inner {
    transition: transform 0.5s cubic-bezier(0.4,0,0.2,1);
}
.rows-inner.no-transition {
    transition: none !important;
}
.row {
    display: flex;
    align-items: center;
    min-height: 1.5vw;
    background: rgba(0,0,0,0.15);
    font-size: 0.8vw;
    font-weight: 500;
}
.row.even {
    background: rgba(0,255,255,0.04);
}
</style>